package com.fr.plugin.provider.controller;

import com.finebi.cbb.utils.CollectionUtils;
import com.fr.decision.authority.AuthorityContext;
import com.fr.decision.authority.data.User;
import com.fr.decision.webservice.Response;
import com.fr.decision.webservice.annotation.LoginStatusChecker;
import com.fr.decision.webservice.v10.user.UserService;
import com.fr.json.JSONObject;
import com.fr.log.FineLoggerFactory;
import com.fr.plugin.provider.ExtendAccessProvider;
import com.fr.plugin.provider.entity.VscAuth;
import com.fr.plugin.provider.req.QueryUserListReq;
import com.fr.plugin.provider.req.QueryVcsListReq;
import com.fr.plugin.provider.req.SetAuthReq;
import com.fr.plugin.provider.resp.QueryAllFileListResp;
import com.fr.plugin.provider.resp.QueryUserListResp;
import com.fr.plugin.provider.resp.VscInfoListResp;
import com.fr.plugin.utils.IpUtil;
import com.fr.plugin.utils.ResponseUtils;
import com.fr.report.entity.VcsEntity;
import com.fr.stable.StringUtils;
import com.fr.stable.query.QueryFactory;
import com.fr.stable.query.condition.QueryCondition;
import com.fr.stable.query.restriction.Restriction;
import com.fr.stable.query.restriction.RestrictionFactory;
import com.fr.third.springframework.stereotype.Controller;
import com.fr.third.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

/***
 * @desc: 报表权限管理配置
 * @author: zhuosh
 * @date: 2022-04-30
 */
@Controller("VcsAuthController")
@LoginStatusChecker(required = false)
@RequestMapping(value = "/vcs/auth")
public class VcsAuthController{

    @RequestMapping( value = "/query/user", method = RequestMethod.POST )
    @ResponseBody
    public Response queryAllUser(@RequestBody QueryUserListReq req){
        try{
            List<User> list = AuthorityContext.getInstance().getUserController().find(QueryFactory.create());
            List<QueryUserListResp> retList = CollectionUtils.ensureNotNull(list).stream()
                    .map(t-> new QueryUserListResp(t.getRealName(),t.getUserName()))
                    .collect(Collectors.toList());
            return Response.ok(retList);
        }catch (Exception e){
            FineLoggerFactory.getLogger().error(e.getMessage(), e);
            return Response.error("500","查询失败");
        }
    }

    /***
     * 查询指定用户的文件列表
     * @param req
     * @return
     */
    @RequestMapping( value = "/query/vcs", method = RequestMethod.POST )
    @ResponseBody
    public Response queryVcsAuth(@RequestBody QueryVcsListReq req){
        FineLoggerFactory.getLogger().info("查询用户文件，请求参数信息为:{}",JSONObject.mapFrom(req).toString());
        try{
            //查询总页数
            Long count = ExtendAccessProvider.queryVcsAuthCount(req);
            if(count == null){
               return ResponseUtils.failQuery();
            }
            Map<String,Object> map = new HashMap<>();
            map.put("count",count);
            if(count == 0){
                map.put("data",Collections.emptyList());
                return ResponseUtils.success(map);
            }

            List<VscAuth> queryList = ExtendAccessProvider.queryVcsAuthList(req);
            List<VscInfoListResp> retList = CollectionUtils.ensureNotNull(queryList).stream().map(t->{
                VscInfoListResp resp = new VscInfoListResp();
                resp.setUserLimit(t.getUserLimit());
                resp.setIpLimit(t.getIpLimit());
                resp.setId(t.getId());
                VcsEntity vcsEntity = ExtendAccessProvider.getByFileName(t.getFileName());
                if(vcsEntity != null){
                    resp.setFileName(vcsEntity.getFilename());
                    resp.setFileId(vcsEntity.getId());
                }
                try {
                    if(!StringUtils.isEmpty(t.getUserLimit())){
                        QueryCondition queryCondition = QueryFactory.create();
                        queryCondition.addRestriction(RestrictionFactory.in("userName",new HashSet<String>(Arrays.asList(t.getUserLimit().split(",")))));
                        List<User> userList = AuthorityContext.getInstance().getUserController().find(queryCondition);
                        resp.setUserName(t.getUserLimit());
                        resp.setRealName(CollectionUtils.ensureNotNull(userList).stream().map(User::getRealName).collect(Collectors.joining(",")));
                    }
                } catch (Exception e) {
                    FineLoggerFactory.getLogger().error("查询用户信息失败", e);
                }
                return resp;
            }).collect(Collectors.toList());
            map.put("data",retList);
            return ResponseUtils.success(map);
        }catch (Exception e){
            FineLoggerFactory.getLogger().error(e.getMessage(), e);
            return ResponseUtils.failQuery();
        }
    }








    @RequestMapping("/query/all/file")
    @ResponseBody
    public Response queryAllFile(){
        try {
            List<VcsEntity> list = ExtendAccessProvider.queryVcsList();
            List<QueryAllFileListResp> fileList = CollectionUtils.ensureNotNull(list).stream().map(t->{
                QueryAllFileListResp resp = new QueryAllFileListResp();
                resp.setId(t.getId());
                resp.setFileName(t.getFilename());
                return resp;
            }).collect(Collectors.toList());
            return ResponseUtils.success(fileList);
        }catch (Exception e){
            FineLoggerFactory.getLogger().error(e.getMessage(), e);
            return ResponseUtils.failQuery();
        }
    }





    /***
     * @param req
     * 对指定文件设置权限
     * @return
     */
    @RequestMapping( value = "/set", method = RequestMethod.POST )
    @ResponseBody
    public Response setSvcAuth(@RequestBody SetAuthReq req){
        if(StringUtils.isBlank(req.getFileName()) || (StringUtils.isBlank(req.getUserNameList()) && StringUtils.isBlank(req.getIpList()))){
            return Response.error("500","参数为空");
        }
        //IP验证
        if(StringUtils.isNotBlank(req.getIpList())){
            String ipLimit = req.getIpList().replace(" ","");
            String[] arr = ipLimit.split(",");
            for(int i=0; i<arr.length; i++){
                if(!IpUtil.ipValid(arr[i])){
                    return Response.error("500",arr[i]+"格式不合法");
                }
            }
            req.setIpList(ipLimit);
        }else{
            req.setIpList("");
        }
        try {
            //校验文件是否存在
            VcsEntity vcsEntity = ExtendAccessProvider.getByFileName(req.getFileName());
            if(vcsEntity == null){
                return Response.error("500","参数为空");
            }
            VscAuth vscAuth = ExtendAccessProvider.queryVcsByFileName(req.getFileName());
            if(vscAuth == null){
                VscAuth insertObj = new VscAuth();
                insertObj.setId(UUID.randomUUID().toString().replace("-",""));
                insertObj.setFileName(req.getFileName());
                insertObj.setUserLimit(req.getUserNameList());
                insertObj.setIpLimit(req.getIpList());
                insertObj.setCreateTime(new Date());
                insertObj.setUpdateTime(new Date());
                ExtendAccessProvider.addVscAuth(insertObj);
            }else{
                vscAuth.setIpLimit(req.getIpList());
                vscAuth.setUserLimit(req.getUserNameList());
                vscAuth.setUpdateTime(new Date());
                ExtendAccessProvider.update(vscAuth);
            }
            return Response.success();
        } catch (Exception e) {
            FineLoggerFactory.getLogger().error(e.getMessage(), e);
            return Response.error("500","设置失败");
        }
    }


    /***
     * 对指定的文件校验和用户做权限校验
     * @param fileName
     * @param username
     * @param ip
     * @return
     */
    public boolean validAuth(String fileName,String username,String ip){
        VcsEntity vcsEntity = ExtendAccessProvider.getByFileName(fileName);
        if(vcsEntity == null){
            return false;
        }
        //查询自己的文件
        if(username.equals(vcsEntity.getUsername())){
            return true;
        }
        VscAuth vscAuth = ExtendAccessProvider.queryVcsByFileName(fileName);
        if(vscAuth == null){
            return true;
        }
        if(!judgeUserName(vscAuth.getUserLimit(),username)){
            return false;
        }
        if(!judgeAllIp(vscAuth.getIpLimit(),ip)){
            return false;
        }
        return true;
    }

    private boolean judgeUserName(String cfgName,String targetName){
        if(StringUtils.isNotBlank(cfgName) && !Arrays.asList(cfgName.split(",")).contains(targetName)){
            return false;
        }
        return true;
    }

    private boolean judgeAllIp(String cfgIp,String targetIp){
        if(StringUtils.isBlank(cfgIp)){
            return true;
        }
        if(StringUtils.isEmpty(targetIp)){
            return false;
        }
        List<String> ipList = Arrays.asList(cfgIp.split(","));
        String[] targetArr = targetIp.split("\\.");
        for(String ip:ipList){
            String[] cfgArr = ip.split("\\.");
            if(targetArr.length != cfgArr.length){
                return false;
            }
            boolean flag = false;
            for(int i=0; i<targetArr.length;i++){
                flag = false;
                if("*".equals(cfgArr[i])){
                    flag = true;
                }else if(cfgArr[i].contains("-")){
                    String[] sub = cfgArr[i].split("-");
                    if(Integer.parseInt(sub[0])<= Integer.parseInt(targetArr[i]) && Integer.parseInt(sub[1]) >= Integer.parseInt(targetArr[i])){
                        flag = true;
                    }
                }else{
                    if( Integer.parseInt(cfgArr[i]) == Integer.parseInt(targetArr[i])){
                        flag = true;
                    }
                }
                if(!flag){
                   break;
                }
            }
            if(flag){
                return true;
            }
        }
        return false;
    }


    /***
     * 删除指定的文件权限
     * @param id
     * @return
     */
    @GetMapping("/delete/{id}")
    @ResponseBody
    public Response deleteAuth(@PathVariable("id") String id){
        FineLoggerFactory.getLogger().info("删除指定文件的权限:{}",id);
        if(StringUtils.isEmpty(id)){
            return ResponseUtils.fail("参数异常");
        }
        try{
            boolean flag = ExtendAccessProvider.deleteVcs(id);
            if(flag){
                return ResponseUtils.success(null);
            }
        }catch (Exception e){
            FineLoggerFactory.getLogger().error(e.getMessage(), e);
        }
        return ResponseUtils.fail("删除失败");
    }
}
